﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Performance
{
    public class Win32Wrapcs
    {
        [DllImport("kernel32.dll", EntryPoint = "GetStdHandle", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int GetStdHandle(uint nStdHandle);

        [DllImport("kernel32.dll", EntryPoint = "GetConsoleScreenBufferInfo", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int GetConsoleScreenBufferInfo(int hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);

        [DllImport("kernel32.dll", EntryPoint = "SetConsoleTextAttribute", SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int SetConsoleTextAttribute(int hConsoleOutput, int wAttributes);

        [StructLayout(LayoutKind.Sequential)]
        private struct COORD { short X; short Y; }

        [StructLayout(LayoutKind.Sequential)]
        private struct SMALL_RECT { short Left; short Top; short Right; short Bottom; }

        [StructLayout(LayoutKind.Sequential)]
        private struct CONSOLE_SCREEN_BUFFER_INFO
        {
            public COORD dwSize;
            public COORD dwCursorPosition;
            public int wAttributes;
            public SMALL_RECT srWindow;
            public COORD dwMaximumWindowSize;
        }

        public static void Run(string text, Action action)
        {
            const uint stdOutputHandle = 0xfffffff5;
            const int green = 2;
            const int red = 12;

            var console = GetStdHandle(stdOutputHandle);
            int originalColor = GetOriginalColor(console);

            try
            {
                SetConsoleTextAttribute(console, green);
                Console.WriteLine(text);
                action();
            }
            catch (Exception ex)
            {
                SetConsoleTextAttribute(console, red);
                Console.WriteLine(ex.Message);
                Console.WriteLine();
            }
            finally
            {
                SetConsoleTextAttribute(console, originalColor);
            }
        }

        private static int GetOriginalColor(int hConsole)
        {
            var consoleInfo = new CONSOLE_SCREEN_BUFFER_INFO();
            GetConsoleScreenBufferInfo(hConsole, ref consoleInfo);
            return consoleInfo.wAttributes;
        }
    }
}
